﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Threading;

namespace MyThreadShow
{
    /*
Task	管理工作单元
Task<TResult>	管理带返回值的工作单元
TaskFactory	创建任务
TaskFactory<TResult>	创建任务或者有相同返回值的延续任务
TaskScheduler	管理任务调度
TaskCompletionSource	手动控制任务工作流
     */
    public partial class Form4Task : Form
    {
        public Form4Task()
        {
            InitializeComponent();
        }

        private  void btnStartTask_Click(object sender, EventArgs e)
        {
            TaskFactory taskFactory = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);

            Task[] tasks = new Task[]
            {
                /*
                 测试结果  task2
                                task1
                                task3
                                task5
                                task4
                                end
                 不是同步的运行
                 */
                taskFactory.StartNew(()=>{Thread.Sleep(1000);Console.WriteLine("task1");}),
                 taskFactory.StartNew(()=>{Thread.Sleep(1000);Console.WriteLine("task2");}),
                  taskFactory.StartNew(()=>{Thread.Sleep(1000);Console.WriteLine("task3");}),
                   taskFactory.StartNew(()=>{Thread.Sleep(1000);Console.WriteLine("task4");}),
                    taskFactory.StartNew(()=>{Thread.Sleep(1000);Console.WriteLine("task5");}),
            };

           // taskFactory.ContinueWhenAny(tasks, (o) => { Console.WriteLine("end"); }, TaskContinuationOptions.ExecuteSynchronously);
            taskFactory.ContinueWhenAll(tasks, (o) => { Console.WriteLine("end"); }, TaskContinuationOptions.ExecuteSynchronously);


            Task task1 = new Task(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("task11");
            });
            Task task2 = task1.ContinueWith((preTask) =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("task12");
            });
            Task task3 = task2.ContinueWith((preTask) =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("task13");
            });
            task1.Start();


            IEnumerable<Action<Task>> actions = new List<Action<Task>>() { 
                new Action<Task>((t)=>{Thread.Sleep(11000);Console.WriteLine("task111");}),
                    new Action<Task>((t)=>{Thread.Sleep(1000);Console.WriteLine("task112");}),
                    new Action<Task>((t)=>{Thread.Sleep(12000);Console.WriteLine("task113");}),
                    new Action<Task>((t)=>{Thread.Sleep(1000);Console.WriteLine("task114");}),
                    new Action<Task>((t)=>{Thread.Sleep(1000);Console.WriteLine("task115");})
            };
            // Create the base task.  Run synchronously.
            var task = new Task(() => { });
            task.RunSynchronously();
            //版本2
            // Chain them all together.
            var query =
                // For each action
                from action in actions

                // Assign the task to the continuation and
                // return that.
                select (task = task.ContinueWith(action));

            // Get the last task to wait on.
            // Note that this cannot be changed to "Last"
            // because the actions enumeration could have no
            // elements, meaning that Last would throw.
            // That means task can be null, so a check
            // would have to be performed on it before
            // waiting on it (unless you are assured that
            // there are items in the action enumeration).
            task = query.LastOrDefault();
        }
    }
}
